package main

import (
	"fmt"
)

/*** 匿名函数和闭包 ***/
func main() {
	a := 10
	str := "tom"
	f1 := func() { //匿名函数没有名字
		fmt.Println("f1")
	}
	f1()

	//定义匿名函数同时调用，这种方式也是闭包
	func() {
		a = 10
		str = "LiLei"
		//在闭包内可以改变外部变量值，影响外部变量值
		fmt.Println("inner a=", a)
		fmt.Println("inner str=", str)
	}() //调用匿名函数
	fmt.Println("outer a=", a)
	fmt.Println("outer str=", str)

	c := func(a, b int) (ret int) {
		ret = a + b
		return
	}(1, 2)
	fmt.Println("c=", c)

	fmt.Println("===== closed package =====")
	//闭包特点：函数返回值是一个匿名函数，返回一个函数类型
	//通过n来调用返回的函数，即闭包函数
	//闭包不关心外部被使用变量的作用域，只要闭包函数还在执行，这些变量就会存在
	n := test01()
	fmt.Println("n=", n())
	fmt.Println("n=", n())
	fmt.Println("n=", n())
}

func test01() func() int {
	//一般的局部变量用完就释放掉了
	var x int
	y := func() int {
		x++
		fmt.Println("x=", x)
		return x * x
	}
	return y
}
